Repository navigation
feat(wallet): actually run the federation server stellar.toml advertises - #1330
Merged
Merged
Conversation
`public/.well-known/stellar.toml` has been publishing
FEDERATION_SERVER = "https://app.useveilapp.xyz/api/federation"
to anyone who looked, while that route did not exist. Every attempt to resolve
a Veil name got Next's HTML 404 where a wallet expected JSON, so Veil was
naming a federation server it did not run. The repo's own comment in the toml
admitted the URL was aspirational — but the file is deployed.
Adds the SEP-2 endpoint and the resolver behind it:
- `type=name` reads `resolve(name)` off `contracts/veil-names`. Expiry needs
no handling: the contract already returns `None` past it, which is what
makes a lapsed name stop resolving instead of quietly paying whoever buys it
next.
- `type=id` answers 404 by design. The registry is keyed name -> address with
no reverse index, so answering would mean scanning every name.
`lib/reverseResolution.ts` already degrades to null and renders the raw
address.
- `type=forward` is a 400, not a 404. The spec reserves it for handing a
payment to an off-network rail and Veil runs none, so "not found" would
imply a right destination might exist.
- `type=txid` is a 404.
The registry contract is not deployed, so every lookup is a truthful 404
today. The shape is the point: a wallet that handles this endpoint now keeps
working the moment the registry is live, and nothing here invents an answer.
`getNamesContractId()` has deliberately no baked-in default, unlike the
factory id, because a placeholder would make the module speak with confidence
about a contract that does not exist.
Two deliberate choices worth stating:
- Names are shape-checked here against `validate_shape` in the contract before
any RPC. It is a short-circuit, not a control — the contract re-checks,
because anyone can invoke it directly — but it keeps a junk query from
costing a metered QuickNode call. A Cyrillic homoglyph is refused rather
than folded to ASCII; folding would let one name resolve to another holder's
payment destination.
- An RPC failure resolves to a 404, never a 500. `lib/federation.ts`
distinguishes 404 ("address not found") from anything else ("server
unreachable"), and a server that 500s on a hiccup teaches callers both that
the name does not resolve and that Veil is unreliable. Only the first is
true.
⚠ Recorded in the module header rather than fixed: a Veil name resolves to a
`C…` address, and SEP-2 documents `account_id` as a Stellar public key. A
classic `payment` cannot address a contract, and CAP-84 `W…` addresses do not
help because a muxed contract address is not a classic destination either. So
a Veil name is payable from Veil and from anything speaking Soroban, and not
from an exchange. Returning the contract address is still right — that is
where the money is, and inventing a `G…` would be worse — but it has to be
settled before a name is marketed as an address you can give anyone. See
docs/IDENTIFIER_ADDRESSES.md.
`npx tsc --noEmit` clean; 32 new tests.
Claude-Session: https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB
Contributor
❌ E2E Tests FailedPlaywright tests failed. Check the uploaded artifacts for:
|
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
public/.well-known/stellar.tomlhas been publishingto anyone who looked, while that route did not exist. Every attempt to resolve
a Veil name got Next's HTML 404 where a wallet expected JSON — Veil was naming
a federation server it did not run. Verified live: that URL returns 404 today.
What this adds
The SEP-2 endpoint and the resolver behind it.
nameresolve(name)offcontracts/veil-nameslib/federation.tssendsidforwardtxidExpiry needs no handling here: the contract already returns
Nonepast it,which is what makes a lapsed name stop resolving rather than quietly paying
whoever buys it next.
The registry contract is not deployed (#1328), so every lookup is a truthful
404 today. The shape is the point — a wallet that handles this endpoint now
keeps working the moment the registry is live, and nothing invents an answer.
getNamesContractId()deliberately has no baked-in default, unlike the factoryid, because a placeholder would make the module speak with confidence about a
contract that does not exist.
Two choices worth stating
validate_shapein thecontract. A short-circuit, not a control — the contract re-checks, since
anyone can invoke it directly — but it stops a junk query costing a metered
QuickNode call. A Cyrillic homoglyph is refused rather than folded to ASCII:
folding would let one name resolve to another holder's payment destination.
lib/federation.tsdistinguishes404 ("address not found") from anything else ("server unreachable"). A server
that 500s on a hiccup teaches callers both that the name does not resolve and
that Veil is unreliable; only the first is true.
⚠ Known, recorded in the module header rather than fixed
A Veil name resolves to a
C…address, and SEP-2 documentsaccount_idas aStellar public key. A classic
paymentcannot address a contract, and CAP-84W…addresses do not help — a muxed contract address is not a classicdestination either. So a Veil name is payable from Veil and from anything
speaking Soroban, and not from an exchange.
Returning the contract address is still correct: that is where the money is,
and inventing a
G…would be worse. But it must be settled before a name ismarketed as an address you can give anyone. See
docs/IDENTIFIER_ADDRESSES.md.Verification
npx tsc --noEmit— cleanPre-existing CI failures, not from this branch
SDK — typecheck, test & size budgetandSecurity Audit — cargo auditfail onevery current PR including frontend-only ones. The SDK one is a real budget
breach on
main: 235.18 kB against a 235 kB limit, over by 175 B. Worth itsown fix rather than silently raising the limit.
https://claude.ai/code/session_01USgemLt4Rnz4SGB1Srf3GB